#include<iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define RGB565_MASK_RED        0xF800
#define RGB565_MASK_GREEN                         0x07E0
#define RGB565_MASK_BLUE                         0x001F

using namespace cv;
using namespace std;
#define IMGW 320
#define IMGH 240
#define YUYVSIZE IMGW*IMGH*2
#define RGBSIZE IMGW*IMGH*3
unsigned char clip255(long v)
{
    if(v < 0)
        v=0;
    else if( v > 255)
        v=255;
    return (unsigned char)v;
}
int YUY2_RGB2_ljh(unsigned char*YUY2buff,unsigned char  *RGBbuff,long dwSize)
{
    unsigned char *orgRGBbuff = RGBbuff;
    long count = 0;
    for( count = 0; count < dwSize; count += 4 )
    {

        //Y0 U0 Y1 V0
        unsigned char Y0 = *YUY2buff;
        unsigned char U = *(++YUY2buff);
        unsigned char Y1 = *(++YUY2buff);
        unsigned char V = *(++YUY2buff);
        ++YUY2buff;
        long Y,C,D,E;
        unsigned char R,G,B;
        Y = Y0;
        C = Y - 16;
        D = U - 128;
        E = V - 128;
        R = clip255(( 298 * C           + 409 * E + 128) >> 8);
        G = clip255(( 298 * C - 100 * D - 208 * E + 128)>> 8);
        B = clip255(( 298 * C + 516 * D           + 128) >> 8);
        *(RGBbuff)   = B;
        *(++RGBbuff) = G;
        *(++RGBbuff) = R;
        Y = Y1;
        C = Y-16;
        D = U-128;
        E = V-128;
        R = clip255(( 298 * C           + 409 * E + 128) >> 8);
        G = clip255(( 298 * C - 100 * D - 208 * E + 128)>> 8);
        B = clip255(( 298 * C + 516 * D           + 128) >> 8);
        *(++RGBbuff) = B;
        *(++RGBbuff) = G;
        *(++RGBbuff) = R;
        ++RGBbuff;
    }
    return 1;
}

int RGB16_2_24(short *RGB16,unsigned char  *RGBbuff,long dwSize)
{
    unsigned char *orgRGBbuff = RGBbuff;
    long count = 0;
    for( count = 0; count < dwSize; count += 2 )
    {
    	 //extract RGB
 orgRGBbuff[2] = (*RGB16 & RGB565_MASK_RED) >> 11;
 orgRGBbuff[1] = (*RGB16 & RGB565_MASK_GREEN) >> 5;
 orgRGBbuff[0] = (*RGB16 & RGB565_MASK_BLUE);
 //amplify the image
 orgRGBbuff[2] <<= 3;
 orgRGBbuff[1] <<= 2;
 orgRGBbuff[0] <<= 3;
 orgRGBbuff+=3;
 RGB16++;
    }
    return 1;
}

void filelock()
{
    FILE *capremf;
    char caprem = 1;
    char *remfilename ="/srv/nfs/arm_rootfs/caprem";
    while(caprem == 1)
    {
        usleep(50*1000);
        // ========read lock
        capremf = fopen(remfilename, "rb");
        if(capremf == NULL)
            caprem = 0;
        else
        {
            fread(&caprem, 1, 1, capremf);
            fclose(capremf);
        }
        // =================
    }
    // ========write lock
    capremf = fopen(remfilename, "wb");
    fwrite(&caprem, 1, 1, capremf);
    fclose(capremf);
    // =================
}

void unfilelock()
{
    FILE *capremf;
    char caprem = 0;
    char *remfilename ="/srv/nfs/arm_rootfs/caprem";
    // ========write lock
    capremf = fopen(remfilename, "wb");
    fwrite(&caprem, 1, 1, capremf);
    fclose(capremf);
    // =================
}

int main()
{
    // 读入一张图片（游戏原画）
    printf("00");
    unsigned char* rgbbuf = (unsigned char*)malloc(RGBSIZE);
    unsigned char* yuy2buf = (unsigned char*)malloc(YUYVSIZE);
    printf("aa");
    char gchr=10;
    unfilelock();
    while(1)
    {

        filelock();

        FILE *srcfp = fopen("/srv/nfs/arm_rootfs/test.yuy2", "rb" );
        if(!srcfp)
        {
            printf("\r /srv/nfs/arm_rootfs/test.yuy2 isn't exist");
        }
        fread(yuy2buf, YUYVSIZE, 1, srcfp);
        RGB16_2_24((short *)yuy2buf, rgbbuf, YUYVSIZE);
        //YUY2_RGB2_ljh(yuy2buf, rgbbuf, YUYVSIZE);
        //convert_yuv_to_rgb_buffer(yuy2buf, rgbbuf, IMGW,IMGH);
        Mat img(IMGH, IMGW, CV_8UC3,Scalar(0));
        memcpy(img.data,rgbbuf, RGBSIZE);
        cout<<img.rows<<endl;
        // 创建一个名为 "游戏原画"窗口
        //cvNamedWindow("游戏原画");
        // 在窗口中显示游戏原画
        imshow("yuyv2rgb",img);
        // 等待6000 ms后窗口自动关闭
        fclose(srcfp);
        unfilelock();
        waitKey(30);
    }
    free(rgbbuf);
    free(yuy2buf);

}
